package com.work.websosket.common;

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Component
@ServerEndpoint(value = "/socket/{name}")
public class WebSocketServer {

    //静态变量，用来记录当前在线连接数。应该把他设计成线程安全的
    private static AtomicInteger online =  new AtomicInteger();

    //concurrent包下的线程安全的map，用来存放每个客户端对应的WebSocket对象
    private static Map<String, Session> sessionPools = new ConcurrentHashMap<>();

    /**
     *发送消息方法
     * @param session 客户端与websocket建立会话
     * @param message 消息
     * @throws IOException
     *
     */
    public void sendMessage(Session session,String message) throws IOException {
        if(session != null){
            session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 连接建立成功调用
     * @param session 客户端与socket建立的会话
     * @param username 客户端的username
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "name") String username) {
        sessionPools.put(username, session);
        addOnlineCount();
        System.out.println(username + "加入WebSocket！当前人数为：" + online);
        try {
            sendMessage(session,"欢迎" + username + "加入连接！ ");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     *关闭连接时调用
     * @param username 关闭连接时的客户端的姓名
     *
     */
    @OnClose
    public void onClose(@PathParam(value = "name") String username) {
        sessionPools.remove(username);
        subOnlineCount();
        System.out.println(username + "断开WebSocket！当前人数为：" + online);
    }

    /*
    *收到客户端消息时触发（群发）
    * @param message
    * @throws IOException
    *
    * */
    @OnMessage
    public void onMessage(String message) throws IOException {
        for (Session session : sessionPools.values()) {
            try {
                sendMessage(session,message);
            } catch (IOException e) {
                e.printStackTrace();
                continue;
            }
        }

    }

    /**
     *发生错误的时候
     * @param session
     * @param throwable
     */
    @OnError
    public void onError(Session session,Throwable throwable) {
        System.out.println("发生错误");
        throwable.printStackTrace();
    }

    /*
    *给指定用户发送消息
    * @param username
    * @param message
    * */
    public void sendInfo(String username,String message) {
        Session session = sessionPools.get(username);
        try {
            sendMessage(session,message);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     *给指定客户端发送消息
     *
     * @param clientId 前端客户端表示
     * @param message 消息
     */
    public void sendInfoClient(String clientId,String message) {
        Session session = sessionPools.get(clientId);
        try {
            sendMessage(session,message);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    /**
     *给指定用户发送消息
     * @param id 用户名
     * @param message 消息
     */
    public void sendInfoUser(String id,String message){
        Set<String> keySet = sessionPools.keySet();
        try {
            for (String key : keySet) {
                if(prefix(key).equals(id)){
                    sendMessage(sessionPools.get(key),message);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    private String prefix(String key){
        return key.substring(0,key.indexOf(":"));
    }

    //判断吧用户是否在线
    public boolean isOnline(String userId){
        Set<String> keySet = sessionPools.keySet();
        for (String key : keySet) {
            if(prefix(key).equals(userId)){
                return true;
            }
        }
        return false;
    }



    public static void addOnlineCount(){

        online.incrementAndGet();
    }

    public static void subOnlineCount(){
        online.decrementAndGet();
    }



}
